package com.axinfu.util.validjsonq;

import com.axinfu.util.validjsonq.exception.ValidJsonQException;
import com.axinfu.util.validjsonq.loader.IsEmptyLoader;
import com.axinfu.util.validjsonq.loader.IsNotEmptyLoader;
import com.axinfu.util.validjsonq.loader.IsNotNullLoader;
import com.axinfu.util.validjsonq.loader.IsNullLoader;
import com.axinfu.util.validjsonq.loader.StringLengthLoader;
import com.axinfu.util.validjsonq.loader.StringRegexLoader;
import com.axinfu.util.validq.validator.IsEmptyValidator;
import com.axinfu.util.validq.validator.IsNotEmptyValidator;
import com.axinfu.util.validq.validator.IsNotNullValidator;
import com.axinfu.util.validq.validator.IsNullValidator;
import com.axinfu.util.validq.validator.StringLengthValidator;
import com.axinfu.util.validq.validator.StringRegexValidator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 基于json规则验证的验证器映射器
 *
 * @author zjn
 * @since 2022/3/23
 */
@SuppressWarnings("all")
public final class ValidQMapper {

    /**
     * 单例
     */
    public static final ValidQMapper INSTANCE = new ValidQMapper();

    /**
     * map结构
     */
    private final Map<String, ValidQElement> classMapperMap = new HashMap<>();

    /**
     * map结构
     */
    private final Map<String, ValidQElement> nameMapperMap = new HashMap<>();

    /**
     * list结构
     */
    private final List<ValidQElement> mapperList = new ArrayList<>();

    private ValidQMapper() {
        regist(IsNullValidator.class, "isNull", new IsNullLoader());
        regist(IsNotNullValidator.class, "isNotNull", new IsNotNullLoader());
        regist(IsEmptyValidator.class, "isEmpty", new IsEmptyLoader());
        regist(IsNotEmptyValidator.class, "isNotEmpty", new IsNotEmptyLoader());
        regist(StringLengthValidator.class, "stringLength", new StringLengthLoader());
        regist(StringRegexValidator.class, "stringRegex", new StringRegexLoader());
    }

    /**
     * 注册验证器
     *
     * @param validatorClass 验证器类
     * @param name           名称
     * @param validQLoader   加载器
     */
    public void regist(Class validatorClass, String name, ValidQLoader validQLoader) {
        String className = validatorClass.getCanonicalName();
        if (classMapperMap.containsKey(className)) {
            throw new ValidJsonQException("验证器类已被注册," + className);
        }
        if (nameMapperMap.containsKey(name)) {
            throw new ValidJsonQException("验证器名称已被注册," + name);
        }
        ValidQElement element = new ValidQElement(className, name, validQLoader);
        classMapperMap.put(className, element);
        nameMapperMap.put(name, element);
        mapperList.add(element);
    }

    /**
     * 获取一个注册对象
     *
     * @param validatorClass 验证类
     * @return 注册对象
     */
    public ValidQElement get(Class validatorClass) {
        String className = validatorClass.getCanonicalName();
        ValidQElement element = classMapperMap.get(className);
        if (null == element) {
            throw new ValidJsonQException("未获取到验证器," + className);
        }
        return element;
    }

    /**
     * 获取一个注册对象
     *
     * @param validatorName 验证器名称
     * @return 注册对象
     */
    public ValidQElement get(String validatorName) {
        ValidQElement element = nameMapperMap.get(validatorName);
        if (null == element) {
            throw new ValidJsonQException("未获取到验证器," + validatorName);
        }
        return element;
    }

    public Map<String, ValidQElement> getClassMapperMap() {
        return classMapperMap;
    }

    public Map<String, ValidQElement> getNameMapperMap() {
        return nameMapperMap;
    }

    public List<ValidQElement> getMapperList() {
        return mapperList;
    }
}
